﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GOFconsole
{
    public class Chapter6_decorator
    {
        public void DecoratorTest()
        {
            //也就是个链式关系，CD2的Operation方法先调CD1的O方法，CD1的O方法又要先调C的O方法
            //就会显得CD1和CD2的新内容像是装饰一样一个个挂在后面
            //Decorator不直接与Component产生联系
            ConcreteComponent c = new ConcreteComponent();
            ConcreteDecoratorA cd1 = new ConcreteDecoratorA();
            ConcreteDecoratorB cd2 = new ConcreteDecoratorB();            
            cd1.SetComponent(c);
            cd2.SetComponent(cd1);
            cd2.Operation();

            //示例
            Person xc = new Person("XC");
            Console.WriteLine("第一种装扮: ");
            TShirts t = new TShirts();
            BigTrouser bt = new BigTrouser();
            Shoes s = new Shoes();

            t.Decorator(xc);
            bt.Decorator(t);
            s.Decorator(bt);
            s.Show();

        }
    }

    /*
     * Component是定义一个接口，可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象，也可以给这个对象
     * 添加一些职责。Decorator,装饰抽象类，继承了Component，从外类扩展Component类的功能，但对于Componenet类来说，是无需
     * 知道Decorator类的存在的。至于ConcreteDecorator就是具体的装饰对象，起到给Component添加职责的功能。  
    */
    #region Component

    abstract class Component
    {
        public abstract void Operation();
    }

    class ConcreteComponent : Component
    {
        public override void Operation()
        {
            Console.WriteLine("具体对象的操作");
        }
    }
    #endregion

    #region Decorator

    abstract class Decorator : Component
    {
        protected Component component;

        public void SetComponent(Component component)
        {
            this.component = component;
        }

        public override void Operation()//重写Operation，实际执行的是Component的Operation()
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }

    class ConcreteDecoratorA : Decorator
    {
        private string addedState;  //本类独有功能，和B区别开来

        public override void Operation()
        {
            base.Operation();       //首先运行原Component的O方法，再执行本类的功能，相当于对原Component进行了装饰
            addedState = "New State";
            Console.WriteLine("具体装饰对象A的操作");
        }
    }

    class ConcreteDecoratorB : Decorator
    {
        public override void Operation()
        {
            base.Operation();
            AddBehavior();
            Console.WriteLine("具体装饰对象B的操作");
        }

        private void AddBehavior() //本类独有功能，和A区别开来
        {
        }

    }


    #endregion

    //示例
    class Person
    {
        public Person()
        { }

        private string name;
        public Person(string name)
        {
            this.name = name;
        }

        public virtual void Show()
        {
            Console.WriteLine("装扮的{0}",name);
        }
    }

    //服饰类(Decorator)
    class Finery : Person
    {
        protected Person component;
        //打扮
        public void Decorator(Person component)
        {
            this.component = component;
        }

        public override void Show()
        {
            if (this.component != null)
            {
                component.Show();
            }
        }
    }

    //具体服饰类
    class TShirts : Finery
    {
        public override void Show()
        {
            Console.Write(" T恤 ");
            base.Show();
        }
    }
    class BigTrouser : Finery
    {
        public override void Show()
        {
            Console.Write(" 大裤衩 ");
            base.Show();
        }
    }
    class Shoes : Finery
    {
        public override void Show()
        {
            Console.Write(" 运动鞋 ");
            base.Show();
        }
    }

}
